package org.xbill.DNS;

import java.io.IOException;
import java.io.Serializable;
import java.util.Iterator;
import java.util.TreeSet;

final class TypeBitmap
  implements Serializable
{
  private static final long serialVersionUID = 226967733L;
  private TreeSet types;

  private TypeBitmap()
  {
    this.types = new TreeSet();
  }

  public TypeBitmap(DNSInput paramDNSInput)
    throws WireParseException
  {
    do
    {
      if (paramDNSInput.remaining() <= 0)
        return;
      if (paramDNSInput.remaining() < 2)
        throw new WireParseException("invalid bitmap descriptor");
      i = paramDNSInput.readU8();
      if (i < -1)
        throw new WireParseException("invalid ordering");
      j = paramDNSInput.readU8();
      if (j > paramDNSInput.remaining())
        throw new WireParseException("invalid bitmap");
      k = 0;
    }
    while (k >= j);
    int l = paramDNSInput.readU8();
    if (l == 0);
    do
    {
      while (true)
        ++k;
      i1 = 0;
    }
    while (i1 >= 8);
    if ((l & 1 << 7 - i1) == 0);
    while (true)
    {
      while (true)
        ++i1;
      int i2 = i1 + i * 256 + k * 8;
      this.types.add(Mnemonic.toInteger(i2));
    }
  }

  public TypeBitmap(Tokenizer paramTokenizer)
    throws IOException
  {
    while (true)
    {
      Tokenizer.Token localToken = paramTokenizer.get();
      if (!(localToken.isString()))
      {
        paramTokenizer.unget();
        return;
      }
      int i = Type.value(localToken.value);
      if (i < 0)
        throw paramTokenizer.exception("Invalid type: " + localToken.value);
      this.types.add(Mnemonic.toInteger(i));
    }
  }

  public TypeBitmap(int[] paramArrayOfInt)
  {
    int i = 0;
    while (true)
    {
      if (i >= paramArrayOfInt.length)
        return;
      Type.check(paramArrayOfInt[i]);
      this.types.add(new Integer(paramArrayOfInt[i]));
      ++i;
    }
  }

  private static void mapToWire(DNSOutput paramDNSOutput, TreeSet paramTreeSet, int paramInt)
  {
    int l;
    int i = 1 + (0xFF & ((Integer)paramTreeSet.last()).intValue()) / 8;
    int[] arrayOfInt = new int[i];
    paramDNSOutput.writeU8(paramInt);
    paramDNSOutput.writeU8(i);
    Iterator localIterator = paramTreeSet.iterator();
    if (!(localIterator.hasNext()))
      l = 0;
    while (true)
    {
      while (l >= i)
      {
        return;
        int j = ((Integer)localIterator.next()).intValue();
        int k = (j & 0xFF) / 8;
        arrayOfInt[k] |= 1 << 7 - j % 8;
      }
      paramDNSOutput.writeU8(arrayOfInt[l]);
      ++l;
    }
  }

  public boolean contains(int paramInt)
  {
    return this.types.contains(Mnemonic.toInteger(paramInt));
  }

  public boolean empty()
  {
    return this.types.isEmpty();
  }

  public int[] toArray()
  {
    int[] arrayOfInt = new int[this.types.size()];
    int i = 0;
    Iterator localIterator = this.types.iterator();
    while (true)
    {
      if (!(localIterator.hasNext()))
        return arrayOfInt;
      int j = i + 1;
      arrayOfInt[i] = ((Integer)localIterator.next()).intValue();
      i = j;
    }
  }

  public String toString()
  {
    StringBuffer localStringBuffer = new StringBuffer();
    Iterator localIterator = this.types.iterator();
    while (true)
    {
      if (!(localIterator.hasNext()))
        return localStringBuffer.substring(0, localStringBuffer.length() - 1);
      localStringBuffer.append(Type.string(((Integer)localIterator.next()).intValue()));
      localStringBuffer.append(' ');
    }
  }

  public void toWire(DNSOutput paramDNSOutput)
  {
    if (this.types.size() == 0)
      return;
    int i = -1;
    TreeSet localTreeSet = new TreeSet();
    Iterator localIterator = this.types.iterator();
    while (true)
    {
      while (!(localIterator.hasNext()))
        mapToWire(paramDNSOutput, localTreeSet, i);
      int j = ((Integer)localIterator.next()).intValue();
      int k = j >> 8;
      if (k != i)
      {
        if (localTreeSet.size() > 0)
        {
          mapToWire(paramDNSOutput, localTreeSet, i);
          localTreeSet.clear();
        }
        i = k;
      }
      localTreeSet.add(new Integer(j));
    }
  }
}